#include "MemoryStream.h"
#include <windows.h>
#include <stdio.h>
#include <sys/stat.h>

#include <iostream> 
#include <fstream> 
using namespace std; 

CMemoryStream::CMemoryStream(char *buffer, long size) {
	this->selfAllocated = false;
	setBuffer(buffer, size);
}
CMemoryStream::CMemoryStream(char *fileName) {
	this->selfAllocated = false;
	setBufferFromFile(fileName);
}

void CMemoryStream::setBufferFromFile(char *fileName) {
	struct stat results;

	if(this->selfAllocated && this->mBuffer) {
		free(this->mBuffer);
	}

	if (stat(fileName, &results) == 0) {
		// allocate buffer
		if(!(this->mBuffer = (char *)malloc(results.st_size))) {
			return;
		}
		this->mSize = results.st_size;
	} else {
		return;
	}
	
	ifstream in(fileName, ios::in | ios::binary); 
	if(!in) {  
		return; 
	}
	
	if(!in.read(this->mBuffer, this->mSize)) {
		DEBUG_PRINT("STREAM READ ERROR\n");
		return;
	}

	this->mPositionPointer = this->mBuffer;
	this->mPosition = 0;
	this->selfAllocated = true;
	
	in.close();
}

void CMemoryStream::setBuffer(char *buffer, long size) {
	if(this->selfAllocated && this->mBuffer) {
		free(this->mBuffer);
	}

	this->mBuffer = buffer;
	this->mSize = size;

	this->mPositionPointer = this->mBuffer;
	this->mPosition = 0;
	this->selfAllocated = false;
}

CMemoryStream::~CMemoryStream(void) {
	if(this->selfAllocated) {
		free(this->mBuffer);
	}
}
int CMemoryStream::read(void* buffer, int sizeToRead) {
	
	if(buffer == NULL)
		return -1;

	if(this->mPosition + sizeToRead > this->mSize)
		sizeToRead = this->mSize - this->mPosition;

	memcpy(buffer, this->mPositionPointer, sizeToRead);
	
	this->mPositionPointer += sizeToRead;
	this->mPosition += sizeToRead;

	return sizeToRead;
}
long CMemoryStream::getSize() const {
	return this->mSize;
}

long CMemoryStream::getPosition() const {
	return this->mPosition;
}